package com.hanhai.zrb.api.biz.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.stereotype.Service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.hanhai.common.bizInterface.ChangeNotify;
import com.hanhai.common.bizInterface.ChangeNotifyUtil;
import com.hanhai.zrb.api.biz.dao.mybatis.IntentionMapper;
import com.hanhai.zrb.api.biz.service.BizMonitorService;
import com.hanhai.zrb.api.biz.service.CityInfoService;
import com.hanhai.zrb.api.biz.service.FundService;
import com.hanhai.zrb.api.biz.service.IndustryService;
import com.hanhai.zrb.api.biz.service.IntentionService;
import com.hanhai.zrb.api.biz.service.ProjectService;
import com.hanhai.zrb.api.biz.service.ResourceMatchCacheManager;
import com.hanhai.zrb.api.biz.service.SysDictionaryService;
import com.hanhai.zrb.api.biz.service.UserDynamicService;
import com.hanhai.zrb.api.biz.service.UserInfoService;
import com.hanhai.zrb.api.biz.service.UserService;
import com.hanhai.zrb.api.biz.service.UserStatisticDetailService;
import com.hanhai.zrb.api.mongodb.SpringContextUtil;
import com.hanhai.zrb.api.solr.SolrHelper;
import com.hanhai.zrb.api.solr.SolrService;
import com.hanhai.zrb.model.common.SysDictionary;
import com.hanhai.zrb.model.common.enums.SysDictionaryEnum;
import com.hanhai.zrb.model.fund.Fund;
import com.hanhai.zrb.model.intention.Intention;
import com.hanhai.zrb.model.intention.dto.IntentionDto;
import com.hanhai.zrb.model.intention.enums.IntentionTypeEnum;
import com.hanhai.zrb.model.project.CityInfo;
import com.hanhai.zrb.model.project.Industry;
import com.hanhai.zrb.model.project.ProjectDetail;
import com.hanhai.zrb.model.resourcematch.ResourceMatchTypeEnum;
import com.hanhai.zrb.model.user.User;
import com.hanhai.zrb.model.user.UserStatisticDetail;
import com.hanhai.zrb.model.user.enums.UserInfoName;
import com.hanhai.zrb.model.userDynamic.DynamicType;

@Service("intentionService")
public class IntentionServiceImpl implements IntentionService,ChangeNotify {

	private Logger logger = LoggerFactory.getLogger(getClass());
	@Resource
	private ResourceMatchCacheManager resourceMatchCacheManager;

	@Resource
	private IntentionMapper intentionMapper;
	@Resource
	private UserService userService;
	@Resource
	private UserInfoService userInfoService;
	@Resource
	private SysDictionaryService sysDictionaryService;
	@Resource
	private UserStatisticDetailService userStatisticDetailService;
	@Resource
	private CityInfoService cityInfoService;
	@Resource
	private IndustryService industryService;
	@Resource
	private ProjectService projectService; 
	@Resource
	private FundService fundService;
	@Resource
	private SolrService solrService;
	
	@Resource
	private UserDynamicService userDynamicService;
	
	
	
	@PostConstruct
	@Override
	public void addListener() {
		ChangeNotifyUtil.addListener(ProjectService.notifySubject_change_authstatus, this);	
		ChangeNotifyUtil.addListener(FundService.notifySubject_change_authstatus, this);
	}

	@Override
	public void change(String subject,Object bizNo) {
		if(StringUtils.equals(subject, ProjectService.notifySubject_change_authstatus)){
			Long projectId = (Long)bizNo;
			doProjectAuthChange(projectId);
		}
		else if(StringUtils.equals(subject, FundService.notifySubject_change_authstatus)){
			Long fundId = (Long)bizNo;
			doFundAuthChange(fundId);
		}
		
	}
	
	/**
	 * 这里实现资金认证状态变化对应的发现认证状态变化的逻辑
	 * @param projectId
	 */
	private void doFundAuthChange(Long fundId){
		List<Intention> intentions = intentionMapper.selectByprojectId(fundId);
		
		if(CollectionUtils.isNotEmpty(intentions)){
			for (Intention intention : intentions) {
				intention.setAuth(null);
				intention.setProjectId(null);
				intentionMapper.updateByPrimaryKey(intention);
			}
		}
		//是否发布
		Fund fund = fundService.findById(fundId);
		if(null !=fund){
		Integer status = fund.getState();
		Long intentionId = fund.getIntention();
		if(status == 203 && intentionId != null){
			Intention intention = intentionMapper.selectByPrimaryKey(intentionId);
			intention.setAuth(fund.getAuth());
			intention.setProjectId(fundId);
			intentionMapper.updateByPrimaryKey(intention);
		}
	}
	}
	/**
	 * 这里实现项目认证状态变化对应的发现认证状态变化的逻辑
	 * @param projectId
	 */
	private void doProjectAuthChange(Long projectId){
		ProjectDetail projectDetail = projectService.qryProjectDetailById(projectId);
		
		List<Intention> intentions = intentionMapper.selectByprojectId(projectId);
		
		if(CollectionUtils.isNotEmpty(intentions)){
			for (Intention intention : intentions) {
				intention.setAuth(null);
				intention.setProjectId(null);
				intentionMapper.updateByPrimaryKey(intention);
				solrService.synIntention(intention.getId());
			}
		}
		
		//是否发布
		Short projectStatus = projectDetail.getProjectStatus();
		Long intentionId = projectDetail.getIntentionId();
		Integer auth = projectDetail.getAuth();
		if(intentionId != null){
			Intention intention = intentionMapper.selectByPrimaryKey(intentionId);
			if(projectStatus == 203){
				intention.setAuth(auth);
				intention.setProjectId(projectId);
				intentionMapper.updateByPrimaryKey(intention);
				solrService.synIntention(intention.getId());
			}
		}
	}
	
	@Override
	public PageInfo findIntentions(IntentionDto intentionDto, int pageNum, int pageSize) {
//		PageHelper.startPage(pageNum, pageSize, true);
//		List<Intention> intentions = intentionMapper.selectAllByCriteria(intentionDto);
		SolrHelper<Intention> solrHelper = new SolrHelper<Intention>(solrService.getSolrIntentionUrl());
		if(StringUtils.isNotBlank(intentionDto.getIndustry()) && !StringUtils.equals("97", intentionDto.getIndustry())){
			solrHelper.andLike("industry", intentionDto.getIndustry());
		}
		if(StringUtils.isNotBlank(intentionDto.getProvince()) && !StringUtils.equals("0", intentionDto.getProvince())){
			solrHelper.andLike("district",intentionDto.getProvince());
		}
		if(null != intentionDto.getStatus()){
			solrHelper.andEquals("status",intentionDto.getStatus().toString());
		}
		if(null != intentionDto.getType()){
			solrHelper.andEquals("type",intentionDto.getType().toString());
		}
		if(null != intentionDto.getStartDate()){
			solrHelper.andDateGreaterThan("pushTime", intentionDto.getStartDate());
		}
		if(null != intentionDto.getEndDate()){
			solrHelper.andDateLessThan("pushTime", intentionDto.getEndDate());
		}
		if (StringUtils.isNotBlank(intentionDto.getKeyWord())) {
			solrHelper.andStartSub();
			List<String> list = userService.findUidByRealNameOrUmobile(intentionDto.getKeyWord());
			if (CollectionUtils.isNotEmpty(list)) {
				solrHelper.orIn("userId", list);
			}
			solrHelper.orLike("intro", intentionDto.getKeyWord());
			solrHelper.endSub();
		}
		
		List<Intention> intentions = solrHelper.execQuery(pageNum, pageSize, "id desc", Intention.class);
		if(CollectionUtils.isNotEmpty(intentions)){
			buildDetails(intentions);
		}
		PageInfo pageInfo = new PageInfo(intentions);
		return pageInfo;
	}
	
	@Override
	public PageInfo findFundList(IntentionDto intentionDto, int pageNum, int pageSize) {
		PageHelper.startPage(pageNum, pageSize, true);
		List<Intention> intentions = intentionMapper.findFundList(intentionDto);
		if(CollectionUtils.isNotEmpty(intentions)){
			buildDetails(intentions);
		}
		PageInfo pageInfo = new PageInfo(intentions);
		return pageInfo;
	}
	
	@Override
	public boolean updateIntention(Intention intention) {
		boolean flag = 1==intentionMapper.updateByPrimaryKeySelective(intention);
		solrService.synIntention(intention.getId());
		Integer type = null;
		if( null!= intention &&  null != intention.getType() && intention.getType().equals(IntentionTypeEnum.project.getCode())){
			type=ResourceMatchTypeEnum.INTENTION_PROJECT.getCode();
		}else if(null!= intention &&  null != intention.getType() &&intention.getType().equals(IntentionTypeEnum.fund.getCode())){
			type=ResourceMatchTypeEnum.INTENTION_FUND.getCode();
		}
		String key =ResourceMatchCacheManagerImpl.buildKey(intention.getId(), type);
		logger.info("Update intention,try to delete the key in redis,key="+key);
		resourceMatchCacheManager.delete(key);
		return flag;
	}

	@Override
	public boolean saveIntention(Intention intention) {
		boolean flag = 1==intentionMapper.insertSelective(intention);
		solrService.synIntention(intention.getId());
		
		BizMonitorService bizMonitorService = this.getBizMonitorService();
		bizMonitorService.intentionPublish(intention);
		return flag;
	}

	@Override
	public Intention getIntention(Long id) {		
		return intentionMapper.selectByPrimaryKey(id);
	}
	
	@Override
	public Intention selectByIdAndUserId(Long id,Long userId){
		return intentionMapper.selectByIdAndUserId(id, userId);
	}
	
	@Override
	public List<Intention> selectByUserId(Long userId) {
		
		return intentionMapper.selectByUserId(userId);
	}

	//单词打错了
	@Override
	public List<Intention> findListDtailesBymaxId(Long userId, Long maxId, Integer limit) {
		if(maxId==null){
			maxId = Long.MAX_VALUE;
		}
		if(limit==null||limit<=0){
			limit=10;
		}
		List<Intention> list = intentionMapper.selectByMaxId(userId,maxId, limit);
		if(CollectionUtils.isNotEmpty(list)){
			buildDetails(list);
		}
		return list;
	}
	
	@Override
	public Intention getDetails(Long id) {
		Intention intention = getIntention(id);
		List<Intention> intentions = Lists.newArrayList(intention);
		if(intention!=null){
			buildDetails(Lists.newArrayList(intention));
		}
		return intentions.get(0);
	}
	
	private void buildDetails(List<Intention> list) {
		List<Long> uids = new ArrayList<Long>();
		List<Long> iids = new ArrayList<Long>();
		for (Intention intention:list) {
			uids.add(intention.getUserId());
			iids.add(intention.getId());
		}
		List<User> userList = userService.findByUid(uids);
		Map<Long,User> userMap = new HashMap<Long,User>();
		for(User user:userList){
			userMap.put(user.getUid(), user);
		}
		Map<Long,Long> icollectionMap = userStatisticDetailService.getCollectionCounterMap(iids, UserStatisticDetail.Type.inten_col);
		Map<Long, Long> attentionMap = userStatisticDetailService.getCollectionCounterMap(iids,UserStatisticDetail.Type.inten_message);
		
		List<SysDictionary> dictionaries = Lists.newArrayList();
		
		dictionaries.addAll(sysDictionaryService.getItemByParentCode(String.valueOf(SysDictionaryEnum.INVEST_TYPE.getType())));
		dictionaries.addAll(sysDictionaryService.getItemByParentCode(String.valueOf(SysDictionaryEnum.INTENTION_TYPE.getType())));
		dictionaries.addAll(sysDictionaryService.getItemByParentCode(String.valueOf(SysDictionaryEnum.PROJECT_STATUS.getType())));
		dictionaries.addAll(sysDictionaryService.getItemByParentCode(String.valueOf(SysDictionaryEnum.FUND_TYPE.getType())));
		dictionaries.addAll(sysDictionaryService.getItemByParentCode(String.valueOf(SysDictionaryEnum.INTENTION_STATUS.getType())));
		
		Map<String, SysDictionary> dictionaryMap = Maps.newHashMap();
		for(SysDictionary dictionary:dictionaries){
			dictionaryMap.put(dictionary.getItemCode(), dictionary);
		}
		
		List<CityInfo> cityInfos = cityInfoService.findAllProvince();
		
		Map<String, String> cityMap = Maps.newHashMap();
		for(CityInfo cityInfo:cityInfos){
			cityMap.put(cityInfo.getPostcode(), cityInfo.getCityName());
		}
		
		List<Industry> industries = industryService.selectAll();
		Map<String, String> industryMap = Maps.newHashMap();
		for(Industry industry:industries){
			industryMap.put(String.valueOf(industry.getId()), industry.getIndustryName());
		}
		
		Map<Long, Map<String, String>> UserInfoMap = userInfoService.findByUidsAndInfoNames(uids, Lists.newArrayList(UserInfoName.POSITION.name()));
		
		
		for (Intention intention:list) {
			User user = userMap.get(intention.getUserId());
			intention.setUserName(StringUtils.isNotBlank(user.getRealname())?user.getRealname():"匿名");
			intention.setPhone(user.getUmobile());
			intention.setAvatar(user.getAvatar());
			intention.setOrg(user.getOrg());
			//这个地方有坑，用户行业选择的是user表的冗余的行业名字，没有拿行业id计算，日后再说
			intention.setUserIndustryName(user.getIndustry());
			if(UserInfoMap.get(user.getUid()) !=null){
				intention.setPosition(UserInfoMap.get(user.getUid()).get(UserInfoName.POSITION.name()));
			}
			
			if(null != intention.getType()){
				intention.setTypeName(dictionaryMap.get(String.valueOf(intention.getType())).getItemName());
			}
			if(null != intention.getMode()){
				intention.setModeName(dictionaryMap.get(String.valueOf(intention.getMode())).getItemName());
			}
			if(intention.getAuth() != null){
				intention.setAuthName(dictionaryMap.get(String.valueOf(intention.getAuth())).getItemName());
			}
			
			String district = intention.getDistrict();
			List<String> districtNames = Lists.newArrayList();
			if(StringUtils.isNotBlank(district)){
				if(StringUtils.contains(district, ",")){
					for(String str:StringUtils.split(district, ",")){
						districtNames.add(cityMap.get(str));
					}
					intention.setDistrictName(StringUtils.join(districtNames.iterator(), "/"));
				}else{
					if(StringUtils.equals("0", district)){
						intention.setDistrictName("全国");
					}else{
						intention.setDistrictName(cityMap.get(district));
					}
				}
			}
			
			String industry = intention.getIndustry();
			List<String> industryNames = Lists.newArrayList();
			if(StringUtils.isNotBlank(industry)){
				if(StringUtils.contains(industry, ",")){
					for(String str:StringUtils.split(industry, ",")){
						industryNames.add(industryMap.get(str));
					}
					intention.setIndustryName(StringUtils.join(industryNames.iterator(), "/"));
				}else{
					intention.setIndustryName(industryMap.get(industry));
				}
			}
			
			Long iCount = icollectionMap.get(intention.getId());
			if(iCount==null){
				iCount = 0L;
			}
			intention.setAttentionTimes(iCount);
			
			Long mCount = attentionMap.get(intention.getId());
			if(mCount==null){
				mCount = 0L;
			}
			intention.setMessageAmount(mCount);
		}
	}
	
	@Override
	public List<Intention> getIntentionList(List<Long> ids) {
		return intentionMapper.getIntentionsByIds(ids);
	}

	@Override
	public boolean batchUpdateIntention(List<Intention> intentions) {
		  for (Intention intention : intentions) {
			this.updateIntention(intention);
		}
		  return true;
	}

	@Override
	public boolean multiDelete(List<Long> ids) {
		boolean flag = intentionMapper.multiDelete(ids)>0;
		for(Long id:ids){
			solrService.synIntention(id);
		}
		return flag;
	}

    @Override
	public Map<Long,Intention> getIntentionMap(List<Long> ids) {
		Map<Long,Intention> map = new HashMap<Long,Intention>(); 
		List<Intention> intentionList = getIntentionList(ids);
		if(CollectionUtils.isNotEmpty(intentionList)){
			for(Intention intention:intentionList){
				map.put(intention.getId(), intention);
			}
		}
		return map;
	}

	@Override
	public List<Intention> selectByUserIdAndType(Long userId, Integer type) {
		return intentionMapper.selectByUserIdAndType(userId, type);
	}

	@Override
	public int countAllUserIntention(Long uid) {
		return intentionMapper.countByUid(uid);
	}
	
	private BizMonitorService getBizMonitorService() throws BeansException { 
        return (BizMonitorService) SpringContextUtil.getBean("bizMonitorService"); 
	} 
}
